package order

import (
	"context"
	"github.com/gin-gonic/gin"
	"nnxy-search-api/search-order-api/api"
	"nnxy-search-api/search-order-api/global"
	"nnxy-search-api/search-order-api/global/response"
	"nnxy-search-api/search-order-api/proto"
	"nnxy-search-api/search-order-api/utils"
	"nnxy-search-api/search-order-api/validator/forms"
	proto2 "nnxy-search-api/search-user-api/proto"
	"strconv"
)

func New(ctx *gin.Context) {
	orderForm := forms.OrderFrom{}
	err := ctx.ShouldBindJSON(&orderForm)
	if err != nil {
		api.HandleValidatorError(err, ctx)
		return
	}
	typeInt, _ := strconv.Atoi(orderForm.Type)
	CategoryId, _ := strconv.Atoi(orderForm.CategoryId)
	req := proto.OrderRequest{
		Uid:        utils.GetContextUserId(ctx),
		Title:      orderForm.Title,
		Type:       int32(typeInt),
		CategoryId: int64(CategoryId),
		ImgUrl:     orderForm.ImgUrl,
		Desc:       orderForm.Desc,
		About:      orderForm.About,
	}
	rsp, err := global.OrderSrvClient.CreateOrder(context.Background(), &req)
	if err != nil {
		api.HandlerGrpcErrorToHttp(err, ctx)
		return
	}
	go func() {
		_, _ = global.OrderSrvClient.MathOrder(context.Background(), &proto.MathOrderRequest{OrderId: int64(rsp.Id)})
	}()
	response.SuccessMsgData(ctx, "发布成功", conventOrderToRsp(rsp, ""))
}

func Math(ctx *gin.Context) {
	orderId := ctx.Param("id")
	orderIdInt, _ := strconv.Atoi(orderId)
	_, err := global.OrderSrvClient.MathOrder(context.Background(), &proto.MathOrderRequest{OrderId: int64(orderIdInt)})
	if err != nil {
		api.HandlerGrpcErrorToHttp(err, ctx)
	}
	response.Success(ctx)
}

func MeList(ctx *gin.Context) {
	pageStr := ctx.DefaultQuery("page", "1")
	limitStr := ctx.DefaultQuery("limit", "10")
	page, _ := strconv.Atoi(pageStr)
	limit, _ := strconv.Atoi(limitStr)
	req := proto.OrderRequest{
		Page:  int32(page),
		Limit: int32(limit),
	}
	userId := utils.GetContextUserId(ctx)
	req.Uid = int64(userId)
	if orderSn := ctx.Query("order_sn"); orderSn != "" {
		req.OrderSn = orderSn
	}
	if status := ctx.Query("status"); status != "" {
		statusInt, _ := strconv.Atoi(status)
		req.Status = int32(statusInt)
	}
	if categoryId := ctx.Query("category_id"); categoryId != "" {
		categoryId, _ := strconv.Atoi(categoryId)
		req.CategoryId = int64(categoryId)
	}
	if title := ctx.Query("title"); title != "" {
		req.Title = title
	}
	if claimAddress := ctx.Query("claim_address"); claimAddress != "" {
		req.ClaimAddress = claimAddress
	}
	if claimName := ctx.Query("claim_name"); claimName != "" {
		req.ClaimName = claimName
	}
	if claimMobile := ctx.Query("claimMobile"); claimMobile != "" {
		req.ClaimMobile = claimMobile
	}

	rsp, err := global.OrderSrvClient.GetOrderList(context.Background(), &req)
	if err != nil {
		api.HandlerGrpcErrorToHttp(err, ctx)
		return
	}
	result := map[string]interface{}{
		"total": rsp.Total,
		"page":  page,
		"limit": limit,
	}
	data := make([]map[string]interface{}, 0)
	for _, order := range rsp.Data {
		data = append(data, conventOrderToRsp(order, ""))
	}
	result["data"] = data
	response.SuccessData(ctx, result)
}

func MathList(ctx *gin.Context) {
	pageStr := ctx.DefaultQuery("page", "1")
	limitStr := ctx.DefaultQuery("limit", "10")
	page, _ := strconv.Atoi(pageStr)
	limit, _ := strconv.Atoi(limitStr)
	req := proto.MathOrderRequest{
		Page:  int32(page),
		Limit: int32(limit),
	}
	if title := ctx.Query("title"); title != "" {
		req.Title = title
	}
	if mathTitle := ctx.Query("math_title"); mathTitle != "" {
		req.MathTitle = mathTitle
	}
	rsp, err := global.OrderSrvClient.GetMathOrderList(context.Background(), &req)
	if err != nil {
		api.HandlerGrpcErrorToHttp(err, ctx)
		return
	}
	result := map[string]interface{}{
		"total": rsp.Total,
		"page":  page,
		"limit": limit,
	}
	data := make([]map[string]interface{}, 0)
	for _, math := range rsp.Data {
		data = append(data, gin.H{
			"id":           math.Id,
			"order_title":  math.OrderTitle,
			"math_title":   math.OrderMathTitle,
			"order_id":     math.OrderId,
			"order_mathId": math.OrderMathId,
			"img_url":      math.OrderImgUrl,
			"math_img_url": math.OrderMathImgUrl,
			"optimal":      math.Optimal,
			"math_time":    math.MathTime,
		})
	}
	result["data"] = data
	response.SuccessData(ctx, result)
}

func List(ctx *gin.Context) {

	pageStr := ctx.DefaultQuery("page", "1")
	limitStr := ctx.DefaultQuery("limit", "10")
	page, _ := strconv.Atoi(pageStr)
	limit, _ := strconv.Atoi(limitStr)
	req := proto.OrderRequest{
		Page:  int32(page),
		Limit: int32(limit),
	}
	if orderSn := ctx.Query("order_sn"); orderSn != "" {
		req.OrderSn = orderSn
	}
	if status := ctx.Query("status"); status != "" {
		statusInt, _ := strconv.Atoi(status)
		req.Status = int32(statusInt)
	}
	if orderTypeStr := ctx.Query("type"); orderTypeStr != "" {
		orderType, _ := strconv.Atoi(orderTypeStr)
		req.Type = int32(orderType)
	}
	if categoryId := ctx.Query("category_id"); categoryId != "" {
		categoryId, _ := strconv.Atoi(categoryId)
		req.CategoryId = int64(categoryId)
	}
	if title := ctx.Query("title"); title != "" {
		req.Title = title
	}
	if claimAddress := ctx.Query("claim_address"); claimAddress != "" {
		req.ClaimAddress = claimAddress
	}
	if claimName := ctx.Query("claim_name"); claimName != "" {
		req.ClaimName = claimName
	}
	if claimMobile := ctx.Query("claimMobile"); claimMobile != "" {
		req.ClaimMobile = claimMobile
	}

	rsp, err := global.OrderSrvClient.GetOrderList(context.Background(), &req)
	if err != nil {
		api.HandlerGrpcErrorToHttp(err, ctx)
		return
	}
	result := map[string]interface{}{
		"total": rsp.Total,
		"page":  page,
		"limit": limit,
	}
	data := make([]map[string]interface{}, 0)
	for _, order := range rsp.Data {
		data = append(data, conventOrderToRsp(order, ""))
	}
	result["data"] = data
	response.SuccessData(ctx, result)
}

func Detail(ctx *gin.Context) {
	id, _ := strconv.Atoi(ctx.Param("id"))
	req := proto.OrderInfoRequest{
		Id: int64(id),
	}
	userIdStr, ok := ctx.Get("user_id")

	if ok && userIdStr != nil {
		req.Uid = int64(userIdStr.(uint))
	}
	rsp, err := global.OrderSrvClient.GetOrderInfoById(context.Background(), &req)
	if err != nil {
		api.HandlerGrpcErrorToHttp(err, ctx)
		return
	}
	userInfo, err := global.UserSrvClient.GetUserInfoById(context.Background(), &proto2.IdRequest{Id: uint32(rsp.Uid)})
	if err != nil {
		api.HandlerGrpcErrorToHttp(err, ctx)
		return
	}
	response.SuccessData(ctx, conventOrderToRsp(rsp, userInfo.Mobile))
}

func Update(ctx *gin.Context) {
	id, _ := strconv.Atoi(ctx.Param("id"))
	orderForm := forms.OrderFrom{}
	err := ctx.ShouldBindJSON(&orderForm)
	if err != nil {
		api.HandleValidatorError(err, ctx)
		return
	}
	CategoryId, _ := strconv.Atoi(orderForm.CategoryId)
	req := proto.OrderRequest{
		Id:         int64(id),
		Uid:        utils.GetContextUserId(ctx),
		CategoryId: int64(CategoryId),
		Title:      orderForm.Title,
		ImgUrl:     orderForm.ImgUrl,
		Desc:       orderForm.Desc,
		About:      orderForm.About,
	}
	_, err = global.OrderSrvClient.UpdateOrder(context.Background(), &req)
	if err != nil {
		api.HandlerGrpcErrorToHttp(err, ctx)
		return
	}
	response.Success(ctx)
}

func Delete(ctx *gin.Context) {
	id, _ := strconv.Atoi(ctx.Param("id"))
	req := proto.OrderRequest{
		Id: int64(id),
	}
	_, err := global.OrderSrvClient.DeleteOrder(context.Background(), &req)
	if err != nil {
		api.HandlerGrpcErrorToHttp(err, ctx)
		return
	}
	response.SuccessMsg(ctx, "删除成功")
}

// CheckClaim 审核
func CheckClaim(ctx *gin.Context) {
	id, _ := strconv.Atoi(ctx.Param("id"))
	checkForm := forms.CheckForm{}
	err := ctx.ShouldBindJSON(&checkForm)
	if err != nil {
		api.HandleValidatorError(err, ctx)
		return
	}
	status := 3
	if checkForm.Type == "1" {
		status = 1
	}
	_, err = global.OrderSrvClient.CheckClaim(context.Background(), &proto.OrderRequest{Id: int64(id), About: checkForm.About, Status: int32(status)})
	if err != nil {
		api.HandlerGrpcErrorToHttp(err, ctx)
		return
	}
	response.Success(ctx)
}

// Claim 认领
func Claim(ctx *gin.Context) {
	id, _ := strconv.Atoi(ctx.Param("id"))
	claimForm := forms.ClaimOrderFrom{}
	err := ctx.ShouldBindJSON(&claimForm)
	if err != nil {
		api.HandleValidatorError(err, ctx)
		return
	}

	_, err = global.OrderSrvClient.ClaimOrder(context.Background(),
		&proto.OrderClaimRequest{
			Id:           int64(id),
			About:        claimForm.About,
			ClaimAddress: claimForm.ClaimAddress,
			ClaimName:    claimForm.ClaimName,
			ClaimMobile:  claimForm.ClaimMobile,
		})
	if err != nil {
		api.HandlerGrpcErrorToHttp(err, ctx)
		return
	}
	response.Success(ctx)
}

func conventOrderToRsp(order *proto.OrderInfoRsp, mobile string) map[string]interface{} {
	item := map[string]interface{}{
		"id":            order.Id,
		"uid":           order.Uid,
		"type":          order.Type,
		"title":         order.Title,
		"order_sn":      order.OrderSn,
		"status":        order.Status,
		"category_id":   order.CategoryId,
		"category_name": order.CategoryName,
		"img_url":       order.ImgUrl,
		"desc":          order.Desc,
		"claim_address": order.ClaimAddress,
		"claim_name":    order.ClaimName,
		"claim_mobile":  order.ClaimMobile,
		"about":         order.About,
		"check_time":    order.CheckTime,
		"claim_time":    order.ClaimTime,
		"create_time":   order.CreateTime,
		"mobile":        mobile,
	}
	return item
}
